<?php
abstract class Controller{
	//需要调用的模型
	protected $model=null;
	
	//控制器名称
    protected $name =  '';

    //模板实例对象
    protected $tpl   =  null;
    
    function __construct()
    {
		if (null == $this->model) {
			$ctl = $this->getCtrlName();
			$_model_front = $ctl;
			
			if(strpos($ctl,"Admin") !== false){
				$_model_admin = substr($ctl,5);
			}
		
			if(class_exists("Model_" . $_model_front)){
				_trace("Loaded DefaultModel Model_$_model_front");
				$this->model = M($_model_front);
			} else if(class_exists("Model_" . $_model_admin)){
				_trace("Loaded DefaultModel Model_$_model_admin");				
				$this->model = M($_model_admin);
			} else {
				_trace("Cannot Load DefaultModel!");
			}
		}
	}
	
    //overloading function
    function __call($method, $args){
    	if (is_object($this->model)) {
    		return call_user_func_array(array($this->model, $method), $args);
    	} else {
    		throw new GiException("No $method Method in This Controller");
    	}
    }
    
	function goBack($msg=""){
		$url = $this->getBack();
		$_SESSION['history']['back'] = null;
		$this->redirect($url,$msg);
	}
	
	function getBack(){
		$url = $_SESSION['history']['back'];
		empty($url) && $url = $_SERVER['HTTP_REFERER'];
		return $url;
	}
	
	function setBack($url=""){
		$_SESSION['history']['back'] = $url ? $url : $_SERVER['REQUEST_URI'];
		return;
	}
	
	function cleanBack(){
		$_SESSION['history']['back'] = null;
		return;
	}
	/**
	 * 跳转URL 
	 * 如果没有msg,则使用header跳转。 如果有msg,则使用html的meta方式跳转。
	 * @param string $url
	 * @param string $msg
	 */
	function redirect($url,$msg = ''){
		$view = _getView("Front");
		$data['delay'] = empty($msg) ? 0 : 2;
		$data['msg']   = $msg;
		$data['url']   = $url;
		if(0 == $data['delay']){
			header("Location:$url");
		} else {
			$view->assign("_data",$data);
			$view->display("Redirect");
		}
	}
	

    function url($action="",$parameter=""){
    	$Ctrl = $this->getCtrlName();
    	return _url($Ctrl,$action,$parameter);
    }
    
    /**
     * 
     * Get current Ctrl's name. for example, if we give "Controller_RmtBase", it will return "RmtBase"; 
     * if we give nothing, it will take the name of current controller.
     * @param string $controller : the controller's name. such as Controller_RmtBase
     * @return string
     * */
    function getCtrlName($controller = ""){
    	if(empty($controller)){
    		$ctl = NAME_CONTROLLER;
    	} else {
    		$ctl = explode("_",$controller);
    		array_shift($ctl);
    		$ctl = implode($controller,"_");
    	}
    	return $ctl;
    }
    
    /**
     * 
     * Get current action's name. for example, if we give "actionIndex", it will return "Index"; if we give nothing, it will take the name of current action.
     * 
     * @param string $action : the Action's name. such as "actionIndex"
     * 
     * @return string
     * 
     * */
    function getActionName($action = ""){
    	if(empty($action)){
    		$act = NAME_ACTION;
    	} else {
    		$act = substr($action,6);
    	}
    	
    	return $act;
    }
    
    /**
     * Get current parameter string, without Ctrl and action. 
     * if we have parameter string like ?Ctrl="AdminArticle&id=1"
     * it will return "id=1"
     * @return string
     * 
     * */    
    function getParameterString(){
    	$data = $_GET;
    	unset($data[C('VAR_CONTROLLER')],$data[C('VAR_ACTION')]);
    	return http_build_query($data);
    }

    /**
     * assign the variables to the templates
     *
     * @param string $varname
     * @param string $value
     */
    function assign($varname, $value){
		if(!isset($this->tpl)){
			$this->tpl = _getView();
		}
		
		$this->tpl->assign($varname, $value);
    }
    /**
     * display the templates
     * @param string $tpl_name
     */
    function display($tpl_name=""){
    	if(!isset($this->tpl)){
			$this->tpl = _getView();
		}
    	$this->tpl->display($tpl_name);
    }

    /**
     * 操作错误跳转的快捷方法
     * @param string $errorMsg 错误信息
     * @param Boolean $ajax 是否为Ajax方式
     * @return void
     */
    public function error($errorMsg,$ajax=false)
    {
        if($ajax || $this->isAjax()) {
            $this->ajaxReturn('',$errorMsg,0);
        }else {
            $this->goBack($errorMsg);
        }
    }

    /**
     * 操作成功跳转的快捷方法
     * @param string $message 提示信息
     * @param Boolean $ajax 是否为Ajax方式
     * @return void
     */
    public function success($message,$ajax=false)
    {
        if($ajax || $this->isAjax()) {
            $this->ajaxReturn('',$message,1);
        }else {
            $this->goBack($message);
        }
    }

    /**
     * 判断是否为AjAX提交
     * @return bool
     */
    protected function isAjax() {
        if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) ) {
            if(strtolower($_SERVER['HTTP_X_REQUESTED_WITH'])=='xmlhttprequest')
                return true;
        }
        return false;
    }
	
    /**
     * Ajax方式返回数据到客户端
     * @param mixed $data 要返回的数据
     * @param String $info 提示信息
     * @param String $status 返回状态
     * @param String $status ajax返回类型 JSON EVAL
     * @return void
     */
    public function ajaxReturn($data='',$info='',$status='',$type='')
    {
  		if(!isset($this->tpl)){
			$this->tpl = _getView();
		}
		
    	if($this->isAjax()){
    		$this->tpl->showDebug = false;
    	}
    	
        $result  =  array();
        if ("" == $data && is_object($this->tpl) ) {
        	$data = $this->tpl->get();
        }
        
        if($status === '' && is_object($this->tpl)) {
            $status  = $this->tpl->get('error')?0:1;
        }
        if($info=='' && is_object($this->tpl)) {
            if($this->tpl->get('error')) {
                $info =   $this->tpl->get('error');
            }elseif($this->tpl->get('message')) {
                $info =   $this->tpl->get('message');
            }
        }

        $result['status']  =  $status;
        $result['info'] =  $info;
        $result['data'] = $data;
        
        if(empty($type)) $type  =   C('AJAX_RETURN_TYPE');
        if(empty($type)) $type = "JSON";
        switch (strtoupper($type)){
        	case "JSON": 
	            // 返回JSON数据格式到客户端 包含状态信息
	            header("Content-Type:text/html; charset=utf-8");
	            die(json_encode($result));
        	case "EVAL":
	            // 返回可执行的js脚本
	            header("Content-Type:text/html; charset=utf-8");
	            die($data);
	          	
        }
    }

}